/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package newpeer;

/**
 * This application that requires the following additional files:
 *   TreeDemoHelp.html
 *    arnold.html
 *    bloch.html
 *    chan.html
 *    jls.html
 *    swingtutorial.html
 *    tutorial.html
 *    tutorialcont.html
 *    vm.html
 */
import java.awt.Desktop;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.UIManager;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;

import java.net.URL;
import java.io.IOException;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import javax.swing.JOptionPane;
import javax.swing.border.TitledBorder;
import org.farng.mp3.MP3File;
import org.farng.mp3.TagException;
import org.farng.mp3.id3.ID3v1;

public class PanelArchivos extends JPanel
        implements TreeSelectionListener {

    private JEditorPane panelInformacion;
    private JTree tree;
    private static boolean DEBUG = false;

    //Optionally play with line styles.  Possible values are
    //"Angled" (the default), "Horizontal", and "None".
    private static boolean playWithLineStyle = false;
    private static String lineStyle = "Horizontal";

    //Optionally set the look and feel.
    private JScrollPane treeView;
    private Peer padre;
    private JTree treeRemotos;
    private JScrollPane treeViewRemotos;

    public PanelArchivos(Peer padre) {
        super(new GridLayout(1, 2));
        this.padre = padre;
        HashMap<String, PipeAdvertisementArchivo> archivosRemotos = this.padre.darArchivosRemotos();
        //Crear los nodos de archivos compartidos REMOTOS.
        DefaultMutableTreeNode nodoArchivosRemotos = new DefaultMutableTreeNode("Archivos REMOTOS");

        crearNodosArbolArchivosRemotos(nodoArchivosRemotos, archivosRemotos);

        //crear un árbol que permita una sola selección.
        treeRemotos = new JTree(nodoArchivosRemotos);
        treeRemotos.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

        //escucha cuando hay una seleccion en el árbol.
        treeRemotos.addTreeSelectionListener(new TreeSelectionListener() {

            public void valueChanged(TreeSelectionEvent e) {
                //Descargar el archivo Seleccionado :S
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeRemotos.getLastSelectedPathComponent();
                if (node == null) {
                    return;
                }
                if (node.isLeaf()) {
                    int res = JOptionPane.showConfirmDialog(null, "¿Desea descargar el archivo seleccionado?");
                    if (res == JOptionPane.YES_OPTION) {
                        Object nodeInfo = node.getUserObject();
                        if (node.isLeaf()) {
                            InfoArchivo archivo = (InfoArchivo) nodeInfo;
                            //mostrarInformacionArchivoYAbrirArchivo(archivo.rutaArchivo);
                            System.out.print(archivo.nombreArchivo + ":  \n    ");
                            PanelArchivos.this.padre.descargarArchivo(archivo.nombreArchivo, archivo.tamArchivo);
                        }
                    }
                }
            }
        });
        //Create the scroll pane and add the tree to it.
        this.treeViewRemotos = new JScrollPane(treeRemotos);
        treeViewRemotos.setBorder(new TitledBorder("Archivos Remotos"));


        if (playWithLineStyle) {
            System.out.println("line style = " + lineStyle);
            treeRemotos.putClientProperty("JTree.lineStyle", lineStyle);
        }

        Dimension minimumSize = new Dimension(100, 100);
        treeRemotos.setMinimumSize(minimumSize);


        //Crear los nodos de archivos compartidos LOCALES.
        DefaultMutableTreeNode nodoArchivos = new DefaultMutableTreeNode("Archivos");
        DefaultMutableTreeNode nodoArchivosCompartidos = new DefaultMutableTreeNode("Archivos Compartidos");
        crearNodosArbolCompartidos(nodoArchivosCompartidos);
        DefaultMutableTreeNode nodoArchivosDescargados = new DefaultMutableTreeNode("Archivos Descargados");
        crearNodosArbolDescargados(nodoArchivosDescargados);
        nodoArchivos.add(nodoArchivosCompartidos);
        nodoArchivos.add(nodoArchivosDescargados);

        //crear un árbol que permita una sola selección.
        tree = new JTree(nodoArchivos);
        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

        //escucha cuando hay una seleccion en el árbol.
        tree.addTreeSelectionListener(this);

        if (playWithLineStyle) {
            System.out.println("line style = " + lineStyle);
            tree.putClientProperty("JTree.lineStyle", lineStyle);
        }

        //Create the scroll pane and add the tree to it.
        this.treeView = new JScrollPane(tree);
        this.treeView.setBorder(new TitledBorder("Archivos Locales"));

        //Create the HTML viewing pane.
        panelInformacion = new JEditorPane();
        panelInformacion.setEditable(false);
        //initHelp();
        JScrollPane htmlView = new JScrollPane(panelInformacion);

        //Add the scroll panes to a split pane.
        JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        splitPane.setTopComponent(treeView);
        splitPane.setBottomComponent(htmlView);

        minimumSize = new Dimension(100, 50);
        htmlView.setMinimumSize(minimumSize);
        treeView.setMinimumSize(minimumSize);
        splitPane.setDividerLocation(100);
        splitPane.setPreferredSize(new Dimension(500, 300));

        //Add the split pane to this panel.
        add(treeViewRemotos);
        add(splitPane);
    }

    public void abrirArchivo(String rutaArchivo) {
        try {
            Desktop.getDesktop().open(new File(rutaArchivo));
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, "No hay un programa asociado para abrir este tipo de archivo", "Error Abriendo archivo", JOptionPane.ERROR_MESSAGE);
        }

    }

    /** Required by TreeSelectionListener interface. */
    public void valueChanged(TreeSelectionEvent e) {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();

        if (node == null) {
            return;
        }

        Object nodeInfo = node.getUserObject();
        if (node.isLeaf()) {
            InfoArchivo archivo = (InfoArchivo) nodeInfo;
            mostrarInformacionArchivoYAbrirArchivo(archivo.rutaArchivo);
            
        } else {
            //displayURL();
        }
    }

    public void actualizarArchivos() {
        removeAll();
        setLayout(new GridLayout(1, 2));

        //Crear los nodos de archivos compartidos.
        DefaultMutableTreeNode nodoArchivos = new DefaultMutableTreeNode("Archivos");
        DefaultMutableTreeNode nodoArchivosCompartidos = new DefaultMutableTreeNode("Archivos Compartidos");
        crearNodosArbolCompartidos(nodoArchivosCompartidos);
        DefaultMutableTreeNode nodoArchivosDescargados = new DefaultMutableTreeNode("Archivos Descargados");
        crearNodosArbolDescargados(nodoArchivosDescargados);
        nodoArchivos.add(nodoArchivosCompartidos);
        nodoArchivos.add(nodoArchivosDescargados);

        //crear un árbol que permita una sola selección.
        tree = new JTree(nodoArchivos);
        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

        //escucha cuando hay una seleccion en el árbol.
        tree.addTreeSelectionListener(this);

        if (playWithLineStyle) {
            System.out.println("line style = " + lineStyle);
            tree.putClientProperty("JTree.lineStyle", lineStyle);
        }

        //Create the scroll pane and add the tree to it.
        this.treeView = new JScrollPane(tree);

        //Create the HTML viewing pane.
        panelInformacion = new JEditorPane();
        panelInformacion.setEditable(false);
        //initHelp();
        JScrollPane htmlView = new JScrollPane(panelInformacion);

        //Add the scroll panes to a split pane.
        JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        splitPane.setTopComponent(treeView);
        splitPane.setBottomComponent(htmlView);

        Dimension minimumSize = new Dimension(100, 50);
        htmlView.setMinimumSize(minimumSize);
        treeView.setMinimumSize(minimumSize);
        splitPane.setDividerLocation(100);
        splitPane.setPreferredSize(new Dimension(500, 300));

        //Add the split pane to this panel.
        add(treeViewRemotos);
        add(splitPane);
        super.repaint();
    }

    private class InfoArchivo {

        public String nombreArchivo;
        public String rutaArchivo;
        private boolean descargado;
        public String tamArchivo;

        public InfoArchivo(String nombreArchivo, String rutaArchivo, boolean descargado) {
            this.nombreArchivo = nombreArchivo;
            this.rutaArchivo = rutaArchivo;
            this.descargado = descargado;
        }

        @Override
        public String toString() {
            Date fechaDescarga = new Date((new File(rutaArchivo)).lastModified());
            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy - KK:mm a");
            String fechaDescargaS = sdf.format(fechaDescarga);
            if (!descargado) {
                return nombreArchivo;
            } else {
                return nombreArchivo + " - Fecha Descarga " + fechaDescargaS;
            }
        }
    }

    private void mostrarInformacionArchivoYAbrirArchivo(String rutaArchivo) {
        String inicioNegrilla = "<b>";
        String finNegrilla = "</b>";

        if (rutaArchivo.endsWith(".mp3")) {
            try {
                File arch = new File(rutaArchivo);
                MP3File archivoMp3 = new MP3File(arch);
                ID3v1 tagInfo = archivoMp3.getID3v1Tag();
                String albumCancion = tagInfo.getAlbumTitle();
                String artistaCancion = tagInfo.getArtist();
                String nombreCancion = tagInfo.getSongTitle();
                String anoCancion = tagInfo.getYear();
                String lala = "Ruta Archivo: " + rutaArchivo + "\n\nINFO MP3:\n" + "Album artista: " + albumCancion + "\n\nArtista: " + artistaCancion + "\n\nNombre canción: " + nombreCancion + "\n\nAño: " + anoCancion;
                panelInformacion.setText(lala);
            } catch (IOException ex) {
                Logger.getLogger(PanelArchivos.class.getName()).log(Level.SEVERE, null, ex);
            } catch (TagException ex) {
                Logger.getLogger(PanelArchivos.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            panelInformacion.setText("Ruta Archivo: " + rutaArchivo);
        }
        abrirArchivo(rutaArchivo);
        if (DEBUG) {
            System.out.println("Attempted to display a null URL.");
        }
    }

    private void crearNodosArbolCompartidos(DefaultMutableTreeNode top) {
        File rutaCompartidos = new File("../temp/");
        File[] archivosCompartidos = rutaCompartidos.listFiles();
        DefaultMutableTreeNode archivosAudio = new DefaultMutableTreeNode("Audio");
        DefaultMutableTreeNode archivosVideo = new DefaultMutableTreeNode("Video");
        DefaultMutableTreeNode archivosDocumentos = new DefaultMutableTreeNode("Documentos");
        DefaultMutableTreeNode archivosOtros = new DefaultMutableTreeNode("Otros");
        top.add(archivosAudio);
        top.add(archivosVideo);
        top.add(archivosDocumentos);
        top.add(archivosOtros);
        for (int i = 0; i < archivosCompartidos.length; i++) {
            File file = archivosCompartidos[i];
            String nombreArchivo = file.getName();
            DefaultMutableTreeNode nodoArchivo = new DefaultMutableTreeNode(new InfoArchivo(nombreArchivo, file.getAbsolutePath(), false));
            //Filtrar por tipos de archivo
            // archivos de audio mp3, wav, wma
            if (!file.isDirectory()) {
                if (nombreArchivo.endsWith(".mp3") || nombreArchivo.endsWith(".wav") || nombreArchivo.endsWith(".wma")) {
                    archivosAudio.add(nodoArchivo);
                } // archivos de video mpg, avi, mpeg
                else if (nombreArchivo.endsWith(".mpg") || nombreArchivo.endsWith(".avi") || nombreArchivo.endsWith(".mpeg")) {
                    archivosVideo.add(nodoArchivo);
                } //archivos de Tipo Documento pdf, doc, docx, txt
                else if (nombreArchivo.endsWith(".pdf") || nombreArchivo.endsWith(".doc") || nombreArchivo.endsWith(".docx") || file.getName().endsWith(".txt")) {
                    archivosDocumentos.add(nodoArchivo);
                } //otros archivos
                else {
                    archivosOtros.add(nodoArchivo);
                }
            }
        }

    }

    private void crearNodosArbolDescargados(DefaultMutableTreeNode top) {
        File rutaDescargados = new File("../temp/cliente");
        if (!rutaDescargados.exists()) {
            rutaDescargados.mkdirs();
        }
        File[] archivosCompartidos = rutaDescargados.listFiles();
        DefaultMutableTreeNode archivosAudio = new DefaultMutableTreeNode("Audio");
        DefaultMutableTreeNode archivosVideo = new DefaultMutableTreeNode("Video");
        DefaultMutableTreeNode archivosDocumentos = new DefaultMutableTreeNode("Documentos");
        DefaultMutableTreeNode archivosOtros = new DefaultMutableTreeNode("Otros");
        top.add(archivosAudio);
        top.add(archivosVideo);
        top.add(archivosDocumentos);
        top.add(archivosOtros);
        for (int i = 0; i < archivosCompartidos.length; i++) {
            File file = archivosCompartidos[i];
            String nombreArchivo = file.getName();
            DefaultMutableTreeNode nodoArchivo = new DefaultMutableTreeNode(new InfoArchivo(nombreArchivo, file.getAbsolutePath(), true));
            //Filtrar por tipos de archivo
            // archivos de audio mp3, wav, wma
            if (!file.isDirectory()) {
                if (nombreArchivo.endsWith(".mp3") || nombreArchivo.endsWith(".wav") || nombreArchivo.endsWith(".wma")) {
                    archivosAudio.add(nodoArchivo);
                } // archivos de video mpg, avi, mpeg
                else if (nombreArchivo.endsWith(".mpg") || nombreArchivo.endsWith(".avi") || nombreArchivo.endsWith(".mpeg")) {
                    archivosVideo.add(nodoArchivo);
                } //archivos de Tipo Documento pdf, doc, docx, txt
                else if (nombreArchivo.endsWith(".pdf") || nombreArchivo.endsWith(".doc") || nombreArchivo.endsWith(".docx") || file.getName().endsWith(".txt")) {
                    archivosDocumentos.add(nodoArchivo);
                } //otros archivos
                else {
                    archivosOtros.add(nodoArchivo);
                }
            }
        }

    }

    private void crearNodosArbolArchivosRemotos(DefaultMutableTreeNode top, HashMap<String, PipeAdvertisementArchivo> archivosRemotos) {

        DefaultMutableTreeNode archivosAudio = new DefaultMutableTreeNode("Audio");
        DefaultMutableTreeNode archivosVideo = new DefaultMutableTreeNode("Video");
        DefaultMutableTreeNode archivosDocumentos = new DefaultMutableTreeNode("Documentos");
        DefaultMutableTreeNode archivosOtros = new DefaultMutableTreeNode("Otros");
        top.add(archivosAudio);
        top.add(archivosVideo);
        top.add(archivosDocumentos);
        top.add(archivosOtros);
        Collection<PipeAdvertisementArchivo> listaArchivoRemotos = archivosRemotos.values();
        for (PipeAdvertisementArchivo pipeAdvertisementArchivo : listaArchivoRemotos) {
            String nombreArchivo = pipeAdvertisementArchivo.getOSName();
            InfoArchivo ar = new InfoArchivo(nombreArchivo, "", false);
            ar.tamArchivo = pipeAdvertisementArchivo.getTamanoArchivo();
            DefaultMutableTreeNode nodoArchivo = new DefaultMutableTreeNode(ar);
            //Filtrar por tipos de archivo
            // archivos de audio mp3, wav, wma
            if (nombreArchivo.endsWith(".mp3") || nombreArchivo.endsWith(".wav") || nombreArchivo.endsWith(".wma")) {
                archivosAudio.add(nodoArchivo);
            } // archivos de video mpg, avi, mpeg
            else if (nombreArchivo.endsWith(".mpg") || nombreArchivo.endsWith(".avi") || nombreArchivo.endsWith(".mpeg")) {
                archivosVideo.add(nodoArchivo);
            } //archivos de Tipo Documento pdf, doc, docx, txt
            else if (nombreArchivo.endsWith(".pdf") || nombreArchivo.endsWith(".doc") || nombreArchivo.endsWith(".docx") || nombreArchivo.endsWith(".txt")) {
                archivosDocumentos.add(nodoArchivo);
            } //otros archivos
            else {
                archivosOtros.add(nodoArchivo);
            }
        }
    }
}
